﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;


namespace SuperKit
{
    public class ConfigReader {
        public static ConfigReader Instance => _instance ?? (_instance = new ConfigReader());
        private static ConfigReader _instance;

        public static string CONFIG_PATH => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.txt");
        public static string COMMAND_PATH => AppContext.BaseDirectory + "Command.xml";

        private Dictionary<string, string> Params { get; set; }

        public string StartupWindow { get => GetString("StartupWindow"); set => SetValue("StartupWindow", value); }
        public string ZipExe { get => GetString("7ZPath"); set => SetValue("7ZPath", value); }
        public string FFMpegExe { get => GetString("FFMpegPath"); set => SetValue("FFMpegPath", value); }
        public string PythonExe { get => GetString("PythonExe"); set => SetValue("PythonExe", value); }
        public string FastImageCatalog { get => GetString("FastImageCatalog"); set => SetValue("FastImageCatalog", value); }

        public int Volume { get => GetInt("Volume"); set => SetValue("Volume", value); }

        public string Catalog { get => GetString("Catalog"); set => SetValue("Catalog", value); }
        public int CatalogIndex { get => GetInt("CatalogIndex"); set => SetValue("CatalogIndex", value); }
        public int MarkIndex { get => GetInt("MarkIndex"); set => SetValue("MarkIndex", value); }
        public string[] CatalogArray => PickCurrentCatalog("Catalog", "CatalogIndex");
        public string[] MarkArray => PickCurrentCatalog("Catalog", "MarkIndex");

        public int MaxShellCount { get => GetInt("MaxShellCount"); set => SetValue("MaxShellCount", value); }
        public bool KeepFastEditor { get => GetBool("KeepFastEditor"); set => SetValue("KeepFastEditor", value); }
        public bool UseSystemVideoPlayer { get => GetBool("UseSystemVideoPlayer"); set => SetValue("UseSystemVideoPlayer", value); }
        public bool SingleClickPlay { get => GetBool("SingleClickPlay"); set => SetValue("SingleClickPlay", value); }
        public string DefaultDirectory { get => GetString("DefaultDirectory"); set => SetValue("DefaultDirectory", value); }

        public int VideoMakeThread { get => GetInt("VideoMakeThread"); set => SetValue("VideoMakeThread", value); }
        public int GalleryThread { get => GetInt("GalleryThread"); set => SetValue("GalleryThread", value); }
        public float DefaultBytesRate { get => GetFloat("DefaultBytesRate"); set => SetValue("DefaultBytesRate", value); }

        public ConfigReader() {
            var path = AppContext.BaseDirectory + "Config.txt";
            Params = ReadLineFile(path);
        }


        public string[] PickCurrentCatalog(string keyName, string indexName) {
            string catalog = GetString(keyName);
            string[] arr = catalog.Split(Kit.CATALOG_SPLIT);

            int index = GetInt(indexName);
            var catalogStr = Kit.SafeGet(arr, index);
            if (catalogStr != null) {
                return catalogStr.Split(Kit.ELEMENT_SPLIT);
            } else {
                return Kit.EMPTY_LIST;
            }
        }

        public int GetInt(string name, int defaultValue = 0) {
            var v = GetString(name);
            return v.Length == 0 ? defaultValue : int.Parse(v);
        }

        public bool GetBool(string name, bool defaultValue = false) {
            var v = GetString(name);
            return v.Length == 0 ? defaultValue : bool.Parse(v);
        }

        public float GetFloat(string name, float defaultValue = 0f) {
            var v = GetString(name);
            return v.Length == 0 ? defaultValue : float.Parse(v);
        }

        public long GetLong(string name, long defaultValue = 0) {
            var v = GetString(name);
            return v.Length == 0 ? defaultValue : long.Parse(v);
        }

        public double GetDouble(string name, double defaultValue = 0.0) {
            var v = GetString(name);
            return v.Length == 0 ? defaultValue : double.Parse(v);
        }

        public string GetString(string name) {
            string value;
            if (!Params.TryGetValue(name, out value)) {
                return Kit.EMPTY;
            }
            return value;
        }

        public string[] GetStringArray(string name) {
            string s = GetString(name);
            if (Kit.IsEmpty(s)) {
                return Kit.EMPTY_LIST;
            }
            return s.Split(Kit.ELEMENT_SPLIT);
        }

        public void SetValue(string name, string value) {            
            Params[name] = value;
        }

        public void SetValue(string key, int value) {
            SetValue(key, value.ToString());
        }

        public void SetValue(string key, float value) {
            SetValue(key, value.ToString());
        }

        public void SetValue(string key, bool value) {
            SetValue(key, value.ToString());
        }

        public string LastCommand {
            get { return GetString("LastCommand"); }
            set { SetValue("LastCommand", value); }
        }

        public string LastArgs {
            get { return GetString("LastArgs"); }
            set { SetValue("LastArgs", value); }
        }


        public void Save() {
            var path = AppContext.BaseDirectory + "Config.txt";
            StringBuilder sb = new StringBuilder(1024);
            foreach (var i in Params) {
                sb.Append($"{i.Key}={i.Value}\n");
            }
            try {
                File.WriteAllText(path, sb.ToString(), Encoding.UTF8);
            } catch (IOException) {
                // 因为有没有关闭的项目，所以这时候会有问题。
            }
        }

        public static Dictionary<string, string> ReadLineFile(string filePath) {

            Dictionary<string, string> contentDictionary = new Dictionary<string, string>();

            if (!File.Exists(filePath)) {
                return contentDictionary;
            }

            FileStream fileStream = null;

            StreamReader streamReader = null;

            try {
                fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);

                streamReader = new StreamReader(fileStream, Encoding.UTF8);

                fileStream.Seek(0, SeekOrigin.Begin);

                string content = streamReader.ReadLine();

                while (content != null) {
                    // #号表示注释，所以忽略这一行
                    if (Kit.IsComment(content)) {
                        ;
                    } else {
                        if (content.Contains("=")) {
                            string key = content.Substring(0, content.LastIndexOf("=")).Trim();

                            string value = content.Substring(content.LastIndexOf("=") + 1).Trim();

                            if (!contentDictionary.ContainsKey(key)) {
                                contentDictionary.Add(key, value);
                            }
                        }
                    }                    
                    content = streamReader.ReadLine();
                }
            } catch {
            } finally {
                if (fileStream != null) {
                    fileStream.Close();
                }
                if (streamReader != null) {
                    streamReader.Close();
                }
            }
            return contentDictionary;
        }

        public void SetInt(string key, int value) {
            SetValue(key, value.ToString());
        }

        public void SetFloat(string key, float value) {
            SetValue(key, value.ToString());
        }

        public void SetBoolean(string key, bool value) {
            SetValue(key, value.ToString());
        }
    }
}
